#include "app.h"
#include <stdio.h>

#define buf_size    10000
uint8_t buf[buf_size];


sint32_t my_ftest_mini()
{
    OS_FILE_t *file;

    printf("======= test mini =======\n");

    printf("- DirRecursive, step1\n");

    OS_fmkdir("folder1");
    OS_fmkdir("folder2");
    OS_fmkdir("folder3");

    DirRecursive("/");

    OS_fdelete("folder1");
    //OS_fdelete("folder2");

    //OS_frename("folder2","ciao");
    //OS_frename("not_existing","ciao");

    //OS_fmkdir("folder3");
    //OS_fmkdir("folder4");

    printf("- DirRecursive, step2\n");

    DirRecursive("/");
}

sint32_t my_ftest_list()
{
    OS_FILE_t *file;

    printf("======= f test list =======\n");

    printf("- DirRecursive\n");

    DirRecursive("/");

    file = OS_fopen("/", "r");
    if (file == NULL)
    {
    }
    else
    {
        OS_fclose(file);
    }
}

sint32_t my_ftest()
{
    OS_FILE_t *file;
    sint32_t  count;
    uint32_t  i;
    uint32_t  j;
    uint32_t  k;

    printf("======= test =======\n");

    for (i = 0; i < 10; i++)
    {
        printf("step-%ld\n", i);
        printf("-------\n");
        printf("\n");

        OS_fmkdir("folder1");
        OS_fmkdir("folder2");
        OS_fmkdir("dir");
        OS_fmkdir("/dir/subdir");

        file = OS_fopen("/dir/subdir/test.txt", "w");
        if (file == NULL)
        {
            deadbeaf("my_ftest, failure step1");
            return -1;
        }
        count = OS_fwrite(buf, 1, 4000, file);
        OS_fclose(file);

        my_memset(buf, 0, 4000);
        file = OS_fopen("/dir/subdir/test.txt", "r");
        if (file == NULL)
        {
            deadbeaf("my_ftest, failure step2");
            return -1;
        }
        count = OS_fread(buf, 1, 4000, file);
        OS_fclose(file);
        //printf("(%s)\n", buf);

        printf("- DirRecursive\n");
        DirRecursive("/");

        OS_fdelete("/dir/subdir/test.txt");
        OS_fdelete("/dir/subdir");
        OS_fdelete("/dir");

        printf("- DirRecursive\n");
        DirRecursive("/");

        /* ----------------------------------- */

        for (k = 0; k < 5; k++)
        {
            sprintf(buf, "/dir%ld", k);
            OS_fmkdir(buf);
            for (j = 0; j < 10; j++)
            {
                sprintf(buf, "/dir%ld/file%ld%ld", k, k, j);
                file = OS_fopen(buf, "w");
                if (file != 0)
                {
                    sprintf(buf, "data chunk (i=%ld,j=%ld)", k, j);
                    OS_fwrite(buf, 1, 8, file);
                    OS_fclose(file);
                }
                else
                {
                    printf("OS_fopen failure at i=%ld j=%ld\n", k, j);
                }
            }
        }
    }
}

int my_test_big(void)
{
    OS_FILE_t *file;
    int       count;
    int       i, j;

    printf("======= test big =======\n");
    printf("-------\n");
    printf("\n");

    printf("step0\n");
    memset(buf, 0, 5000);
    for (count = 0; count < 4000; ++count)
    {
        buf[count] = (char) ('A' + (count % 26));
    }

    printf("step1\n");
    OS_fmkdir("dir");

    printf("step2\n");
    OS_fmkdir("/dir/subdir");

    printf("step3\n");
    file = OS_fopen("/dir/subdir/test.txt", "w");
    if (file == NULL)
    {
        deadbeaf("OS_ftest, failure step3");
        return -1;
    }
    printf("step4\n");
    count = OS_fwrite(buf, 1, 4000, file);
    OS_fclose(file);

    my_memset(buf, 0, 5000);
    file = OS_fopen("/dir/subdir/test.txt", "r");
    if (file == NULL)
    {
        deadbeaf("OS_ftest, failure step4");
        return -1;
    }
    count = OS_fread(buf, 1, 5000, file);
    OS_fclose(file);
    printf("(%s)\n", buf);

    printf("step4\n");
    DirRecursive("/");

    for (i = 0; i < 5; ++i)
    {
        sprintf(buf, "/dir%d", i);
        OS_fmkdir(buf);
        for (j = 0; j < 5; ++j)
        {
            sprintf(buf, "/dir%d/file%d%d", i, i, j);
            file = OS_fopen(buf, "w");
            if (file)
            {
                sprintf(buf, "i=%d j=%d", i, j);
                OS_fwrite(buf, 1, 8, file);
                OS_fclose(file);
            }
        }
    }

    OS_fdelete("/dir1/file12");
    DirRecursive("/");
    file = OS_fopen("/baddir/myfile.txt", "w");
    if (file == 0)
    {
        printf("ERROR!\n");
    }
    else
    {
        printf("expected ERROR!\n");
        while (True)
        {
            ;
        }
    }
    printf("---------- step last -----------\n");
    for (i = 0; i < 5; ++i)
    {
        for (j = 0; j < 5; ++j)
        {
            sprintf(buf, "/dir%d/file%d%d", i, i, j);
            file = OS_fopen(buf, "r");
            if (file != 0)
            {
                count = OS_fread(buf, 1, 500, file);
                printf("i=%d j=%d count=%d (%s)\n", i, j, count, buf);
                OS_fclose(file);
            }
        }
    }

    OS_fdelete("/dir/subdir/test.txt");
    OS_fdelete("/dir/subdir");
    OS_fdelete("/dir");
    for (i = 0; i < 5; ++i)
    {
        for (j = 0; j < 5; ++j)
        {
            sprintf(buf, "/dir%d/file%d%d", i, i, j);
            OS_fdelete(buf);
        }
        sprintf(buf, "/dir%d", i);
        OS_fdelete(buf);
    }

    printf("--- file list at the end ---\n");
    OS_fmkdir("my_folder");
    OS_fmkdir("my_folder/hAllo");
    DirRecursive("/");
    printf("----------------------------\n");

    return 0;
}

void size_show()
{
    printf("====== fs internal objs size ======\n");
    printf("sizeof(OS_FileEntry_t) = %d\n", sizeof(OS_FileEntry_t));
    printf("sizeof(OS_Block_t)     = %d\n", sizeof(OS_Block_t));
    printf("sizeof(OS_FILE_t)      = %d\n", sizeof(OS_FILE_t));
}

void app()
{
    uint8_t   disk_ID;
    uint8_t   mediaType;
    boolean_t ans;
    boolean_t is_disk_opened;
    boolean_t is_disk_bitmap_opened;

    mediaType = FILE_MEDIA_DISK; /* it does not support others */
    disk_ID   = 0;

    is_disk_opened        = disk_init(disk_ID);
    is_disk_bitmap_opened = disk_bitmap_init(disk_ID);

    ans = is_disk_opened logicalAnd is_disk_bitmap_opened;
    if (ans == True)
    {
        ans = OS_my_mkfs(mediaType);
    }
    if (ans == True)
    {
        ans = OS_my_mount();
    }
    if (ans == True)
    {
        //my_ftest_big();
        //my_ftest();
        //my_ftest_mini();

        //OS_frename("folder2", "hAllo");
        //OS_frename("not_existing","ciao");

        OS_fmkdir("folder1");
        OS_frename("folder1", "folder2");
        //OS_fdelete("folder1");
        //OS_fdelete("folder2");
        /*
         */        OS_fmkdir("folder13");
        OS_fmkdir("folder23");
        OS_fmkdir("folder33");
        OS_fmkdir("folder43");
        OS_fmkdir("folder53");
        OS_fmkdir("folder63");
        OS_fmkdir("folder73");
        OS_fmkdir("folder83");
        OS_fmkdir("foldera3");
        OS_fmkdir("folderb3");
        OS_fmkdir("folderc3");
        OS_fmkdir("folderd3");
        OS_fmkdir("foldere3");
        OS_fmkdir("folderf3");
        OS_fmkdir("folderg3");
        OS_fmkdir("folderh3");
        OS_fmkdir("folderi3");
        OS_fmkdir("folderj3");
        OS_fmkdir("folderj3");
        OS_fmkdir("folderk3");
        OS_fmkdir("folders3");
        OS_fmkdir("foldera3");
        my_ftest_list();
    }

    if (is_disk_opened == True)
    {
        disk_done(disk_ID);
    }
    if (is_disk_bitmap_opened == True)
    {
        disk_bitmap_done(disk_ID);
    }
}


int main()
{
    app();
    size_show();

    return 0;
}
